import { Global, Logger, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import * as dotenv from 'dotenv';
import * as Joi from 'joi';
import { RedisClientOptions, RedisModule } from '@liaoliaots/nestjs-redis';
import { TypeOrmModule } from '@nestjs/typeorm';
import {connectionParams} from '../ormconfig';
import { LogsModule } from './log/log.module';
import { AdminModule } from './modules/admin/admin.module';
import { TagModule } from './modules/tag/tag.module';
import { LinkModule } from './modules/link/link.module';
import { ClassifyModule } from './modules/classify/classify.module';
import { BannerModule } from './modules/banner/banner.module';
import { ArticleModule } from './modules/article/article.module';
import { HomeModule } from './modules/home/home.module';
import { UploadModule } from './modules/upload/upload.module';
import { ConfigEnum } from './enum/config.enum';
const envFilePath = `.env.${process.env.NODE_ENV || `development`}`;

const schema = Joi.object({
  NODE_ENV: Joi.string()
    .valid('development', 'production', 'test')
    .default('development'),
  DB_PORT: Joi.number().default(3306),
  DB_HOST: Joi.alternatives().try(Joi.string().ip(), Joi.string().domain()),
  DB_TYPE: Joi.string().valid('mysql', 'postgres'),
  DB_DATABASE: Joi.string().required(),
  DB_USERNAME: Joi.string().required(),
  DB_PASSWORD: Joi.string().required(),
  RD_HOST: Joi.string().required(),
  RD_PORT: Joi.number().required(),
  DB_SYNC: Joi.boolean().default(false),
  LOG_ON: Joi.boolean(),
  LOG_LEVEL: Joi.string(),
});

@Global()
@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath,
      load: [
        () => {
          const values = dotenv.config({ path: '.env' });
          const { error } = schema.validate(values?.parsed, {
            // 允许未知的环境变量
            allowUnknown: true,
            // 如果有错误，不要立即停止，而是收集所有错误
            abortEarly: false,
          });
          if (error) {
            throw new Error(
              `Validation failed - Is there an environment variable missing?
        ${error.message}`,
            );
          }
          return values;
        },
      ],
      validationSchema: schema,
    }),
    RedisModule.forRootAsync({
      useFactory:(configService:ConfigService) => {
        const config:RedisClientOptions = {
          host: configService.get<string>(ConfigEnum.RD_HOST),
          port: configService.get<number>(ConfigEnum.RD_PORT),
          db:configService.get<number>(ConfigEnum.RD_DB)
        };
        if(process.env.NODE_ENV==='production') {
          config.password = configService.get<string>(ConfigEnum.RD_PASSWORD);
        }
        return {
          config
        };
      },
      inject: [ConfigService]
    }),
    TypeOrmModule.forRoot(connectionParams),
    LogsModule,
    AdminModule,
    ArticleModule,
    BannerModule,
    ClassifyModule,
    LinkModule,
    TagModule,
    HomeModule,
    UploadModule
  ],
  controllers: [],
  providers: [Logger],
  exports: [Logger]
})
export class AppModule {}
